package com.chen.common.satoken;

import cn.dev33.satoken.sso.config.SaSsoClientConfig;
import cn.dev33.satoken.sso.processor.SaSsoClientProcessor;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.chen.base.utils.PropertyUtil;
import com.chen.base.utils.SpringContextHolder;
import com.chen.common.satoken.component.SaApiName;
import com.chen.common.satoken.component.StpInterfaceImpl;
import com.chen.common.satoken.controller.SsoClientController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: ChenJinLong
 * @DATE: 2025/1/7
 **/
@Slf4j
@Configuration
public class SaTokenClientAutoConfig implements ApplicationRunner {

    @Resource
    private SaApiName saApiName;
    @Value("${sa-token.ex.server-name:chen-sa-auth}")
    private String saServerName;

    @Bean
    public SsoClientController ssoClientController(){
        return new SsoClientController();
    }

    @Bean
    public StpInterfaceImpl stpInterfaceImpl(){
        return new StpInterfaceImpl();
    }

    /** 配置SSO相关参数 */
    @Resource
    public void configSso(SaSsoClientConfig ssoClient) {
        // 配置Http请求处理器
        ssoClient.sendHttp = SaTokenAutoConfig.sendHttpFunction();

        // 配置client api 地址
        SaSsoClientProcessor.instance.ssoClientTemplate.apiName.ssoLogin = saApiName.ssoLogin();
        SaSsoClientProcessor.instance.ssoClientTemplate.apiName.ssoLogout = saApiName.ssoLogout();
        SaSsoClientProcessor.instance.ssoClientTemplate.apiName.ssoLogoutCall = saApiName.ssoLogoutCall();
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        String authServerUrl = PropertyUtil.getProperty("sa-token.sso-client.server-url");
        if (StrUtil.isBlank(authServerUrl)){
            // 如果认证中心地址为空，则从注册中心获取地址
            DiscoveryClient discoveryClient = SpringContextHolder.getBean(DiscoveryClient.class);
            List<String> serverList = discoveryClient.getServices()
                    .stream()
                    .filter(s -> s.contains(saServerName))
                    .flatMap(s -> discoveryClient.getInstances(s).stream())
                    .map(instance -> String.format("http://%s:%s", instance.getHost(), instance.getPort()))
                    .collect(Collectors.toList());
            Assert.notEmpty(serverList, "请先启动认证中心!");
            log.info("认证中心地址集: {}", serverList);
            SaSsoClientProcessor.instance.ssoClientTemplate.getClientConfig().serverUrl = serverList.get(0);
        }

        SaSsoClientProcessor.instance.ssoClientTemplate.getClientConfig().isHttp = true;
    }
}
